/**
 * BorrowDevice控制器模块
 * controller\ Borrow.js
 *
 */


const express = require("express");
const util = require("../common/util");
/**
 * @typedef {BorrowDB}
 */
const BorrowDB = require("../model/sqlite/deviceBorrow");

/**
 * 获取设备借用记录信息
 * @param {express.Request} req
 * @param {express.Response} res
 */
function find(req, res) {
  (async function () {
    try {
      let db = BorrowDB.getInstance();
      await db.connect();
      let result = await db.find(req.params.id);
      util.logFormat(`获取设备借用记录【${req.params.id}】信息%O`, result);
      res.json(util.FormatJSONData(200, `获取设备借用记录【${req.params.id}】`, result));
    } catch (err) {
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误", { Error: err }));
    }
  })().catch(err=>{
    util.err(err);
    res.json(util.FormatJSONData(500, "服务器内部错误"));
  });
}

  /**
   * 获取设备借用记录列表
   * @param {express.Request} req
   * @param {express.Response} res
   * GET /borrow-records
   * 查询借用记录，支持分页和过滤
   */
 async function findAll(req, res) {
  try {
    // 从请求查询参数获取分页和过滤条件
    const limit = req.query.limit ? parseInt(req.query.limit) : -1;
    const offset = req.query.offset ? parseInt(req.query.offset) : -1;

    // 组装过滤条件，只传入存在的
    const filters = {};
    if (req.query.status) {
      filters.status = req.query.status;
    }
    if (req.query.deviceId) filters.deviceId = parseInt(req.query.deviceId);

    // 根据用户角色设置权限
    const userRole = req.session.user.role;
    if (userRole !== 1) { // 如果不是管理员，只能查看自己的记录
      filters.userId = req.session.user.id;
    } else if (req.query.userId) { // 管理员可以查看指定用户的记录
      filters.userId = parseInt(req.query.userId);
    }

    let db = BorrowDB.getInstance();
    await db.connect();
    let records = await db.findAll({ limit, offset, filters });
    
    // 返回标准格式的响应
    res.json({
      code: 200,
      msg: "获取预约记录成功",
      data: records || [],
      total: records ? records.length : 0
    });
  } catch (err) {
    console.error('查询借用记录出错', err);
    res.status(500).json({
      code: 500,
      msg: '查询借用记录失败',
      data: null
    });
  }
}


/**
 * 新建设备借用记录（预约）
 * @param {express.Request} req
 * @param {express.Response} res
 */
function add(req, res) {
  (async function () {
    try {
      // 验证必要参数
      const { deviceId, startTime, endTime, purpose } = req.body;
      if (!deviceId || !startTime || !endTime) {
        return res.json(util.FormatJSONData(400, "缺少必要参数：设备ID、开始时间、结束时间"));
      }

      // 验证时间格式和逻辑
      const start = new Date(startTime);
      const end = new Date(endTime);
      const now = new Date();

      if (isNaN(start.getTime()) || isNaN(end.getTime())) {
        return res.json(util.FormatJSONData(400, "时间格式不正确"));
      }

      if (start < now) {
        return res.json(util.FormatJSONData(400, "开始时间不能早于当前时间"));
      }

      if (end <= start) {
        return res.json(util.FormatJSONData(400, "结束时间必须晚于开始时间"));
      }

      const userId = req.session.user.id;
      const borrowData = {
        userId,
        deviceId,
        startTime,
        endTime,
        purpose: purpose || '',
        borrowTime: now.toISOString(),
        status: 'pending'
      };

      let db = BorrowDB.getInstance();
      await db.connect();
      
      // 检查设备是否可预约
      const device = await db.checkDeviceAvailability(deviceId, startTime, endTime);
      if (!device) {
        return res.json(util.FormatJSONData(400, "设备在该时间段已被预约"));
      }

      let result = await db.createBorrowRecord(borrowData);
      util.log(`新增设备预约记录：lastID->${result}`);
      res.json(util.FormatJSONData(201, "预约申请已提交，等待审核", { lastID: result }));
    } catch (err) {
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误", { Error: err.message }));
    }
  })().catch(err => {
    util.err(err);
    res.json(util.FormatJSONData(500, "服务器内部错误"));
  });
}

/**
 * 更新设备借用记录（例如归还）
 * @param {express.Request} req
 * @param {express.Response} res
 */
function update(req, res) {
  (async function () {
    try {
      const { deviceId, userId, status, remarks } = req.body;
      const userRole = req.session.user.role;

      // 验证参数
      if (!deviceId) {
        return res.json(util.FormatJSONData(400, "缺少设备ID"));
      }

      // 如果是管理员，可以更新状态
      if (userRole === 1 && status) {
        const validStatuses = ['approved', 'rejected', 'completed'];
        if (!validStatuses.includes(status)) {
          return res.json(util.FormatJSONData(400, "无效的状态值"));
        }

        let db = BorrowDB.getInstance();
        await db.connect();
        
        try {
          // 更新预约状态
          const result = await db.updateBorrowStatus(deviceId, userId, status, remarks);
          
          if (!result) {
            return res.json(util.FormatJSONData(400, "未找到相关预约记录"));
          }

          util.log(`更新设备预约状态：changes->${result}`);
          res.json(util.FormatJSONData(200, "更新预约状态成功", { changes: result }));
        } catch (dbError) {
          util.err(dbError);
          res.json(util.FormatJSONData(500, "更新预约状态失败: " + dbError.message));
        }
      } else {
        // 普通用户只能归还设备
        if (status !== 'completed') {
          return res.json(util.FormatJSONData(403, "权限不足"));
        }

        let db = BorrowDB.getInstance();
        await db.connect();
        
        try {
          // 归还设备
          const result = await db.returnBorrowRecord(req.session.user.id, deviceId);
          
          if (!result) {
            return res.json(util.FormatJSONData(400, "未找到相关预约记录或设备未借用"));
          }

          util.log(`归还设备：changes->${result}`);
          res.json(util.FormatJSONData(200, "归还设备成功", { changes: result }));
        } catch (dbError) {
          util.err(dbError);
          res.json(util.FormatJSONData(500, "归还设备失败: " + dbError.message));
        }
      }
    } catch (err) {
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误: " + err.message));
    }
  })().catch(err => {
    util.err(err);
    res.json(util.FormatJSONData(500, "服务器内部错误: " + err.message));
  });
}

/**
 * 删除设备借用记录
 * @param {express.Request} req
 * @param {express.Response} res
 */
function remove(req, res) {
  (async function () {
    try {
      let id = req.params.id;
      let db = BorrowDB.getInstance();
      await db.connect();
      let result = await db.remove(id);
      util.log(`删除设备借用记录：changes->${result}`);
      res.json(util.FormatJSONData(204, "删除设备借用记录", { changes: result }));
    } catch (err) {
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误", { Error: err }));
    }
  })().catch(err=>{
    util.err(err);
    res.json(util.FormatJSONData(500, "服务器内部错误"));
  });
}

/**
 * 获取超期未归还的设备列表
 * @param {express.Request} req
 * @param {express.Response} res
 */
async function getOverdueDevices(req, res) {
  try {
    // 检查权限
    if (req.session.user.role !== 1) {
      return res.json(util.FormatJSONData(403, "权限不足"));
    }

    let db = BorrowDB.getInstance();
    await db.connect();
    let overdueDevices = await db.getOverdueDevices();
    
    res.json({
      code: 200,
      msg: "获取超期设备列表成功",
      data: overdueDevices
    });
  } catch (err) {
    console.error('获取超期设备列表失败:', err);
    res.status(500).json({
      code: 500,
      msg: '获取超期设备列表失败',
      data: null
    });
  }
}

/**
 * 归还设备
 * @param {express.Request} req
 * @param {express.Response} res
 */
async function returnDevice(req, res) {
  try {
    const { bookingId, returnNote } = req.body;
    const currentUserId = req.session.user.id;
    const isAdmin = req.session.user.role === 1;

    if (!bookingId) {
      return res.json(util.FormatJSONData(400, "缺少预约记录ID"));
    }

    console.log('Processing device return:', {
      bookingId,
      userId: currentUserId,
      isAdmin,
      returnNote
    });

    let db = BorrowDB.getInstance();
    await db.connect();

    // 根据 bookingId 查询对应的记录
    const booking = await db.find(bookingId);
    console.log('Found booking:', booking);
    
    if (!booking) {
      return res.json(util.FormatJSONData(400, "未找到相关预约记录"));
    }

    // 检查预约记录状态
    if (booking.status !== 'approved') {
      return res.json(util.FormatJSONData(400, "预约记录状态不是已批准"));
    }

    // 检查是否是当前用户的预约
    if (!isAdmin && booking.user_id !== currentUserId) {
      return res.json(util.FormatJSONData(403, "无权归还他人的设备"));
    }

    // 归还设备，传入归还说明
    const result = await db.returnBorrowRecord(bookingId, returnNote || '');
    console.log('Return result:', result);

    if (!result) {
      return res.json(util.FormatJSONData(400, "归还设备失败"));
    }

    res.json({
      code: 200,
      msg: "归还设备成功",
      data: { changes: result }
    });
  } catch (err) {
    console.error('归还设备失败:', err);
    res.status(500).json({
      code: 500,
      msg: '归还设备失败: ' + err.message,
      data: null
    });
  }
}

/**
 * 取消预约
 * @param {express.Request} req
 * @param {express.Response} res
 */
async function cancelBooking(req, res) {
  try {
    const { bookingId, cancelReason } = req.body;
    const userId = req.session.user.id;

    if (!bookingId) {
      return res.json(util.FormatJSONData(400, "缺少预约记录ID"));
    }

    console.log('Processing booking cancellation:', {
      bookingId,
      userId,
      cancelReason
    });

    let db = BorrowDB.getInstance();
    await db.connect();

    // 取消预约
    const result = await db.cancelBooking(bookingId, cancelReason);
    console.log('Cancel result:', result);

    if (!result) {
      return res.json(util.FormatJSONData(400, "未找到可取消的预约记录或预约已开始"));
    }

    res.json({
      code: 200,
      msg: "取消预约成功",
      data: { changes: result }
    });
  } catch (err) {
    console.error('取消预约失败:', err);
    res.status(500).json({
      code: 500,
      msg: '取消预约失败: ' + err.message,
      data: null
    });
  }
}

/**
 * 获取设备使用记录
 * @param {express.Request} req
 * @param {express.Response} res
 */
async function getUsageRecords(req, res) {
  try {
    const deviceId = parseInt(req.params.deviceId);
    const limit = req.query.limit ? parseInt(req.query.limit) : -1;
    const offset = req.query.offset ? parseInt(req.query.offset) : -1;

    let db = BorrowDB.getInstance();
    await db.connect();
    let records = await db.getUsageRecords(deviceId, limit, offset);
    
    res.json({
      code: 200,
      msg: "获取使用记录成功",
      data: records
    });
  } catch (err) {
    console.error('获取使用记录失败:', err);
    res.status(500).json({
      code: 500,
      msg: '获取使用记录失败',
      data: null
    });
  }
}

/**
 * 添加设备使用记录
 * @param {express.Request} req
 * @param {express.Response} res
 */
async function addUsageRecord(req, res) {
  try {
    const deviceId = parseInt(req.params.deviceId);
    const { usageNote } = req.body;
    const userId = req.session.user.id;

    if (!usageNote) {
      return res.json(util.FormatJSONData(400, "缺少使用记录内容"));
    }

    let db = BorrowDB.getInstance();
    await db.connect();
    let result = await db.addUsageRecord(deviceId, userId, usageNote);
    
    res.json({
      code: 201,
      msg: "添加使用记录成功",
      data: { id: result }
    });
  } catch (err) {
    console.error('添加使用记录失败:', err);
    res.status(500).json({
      code: 500,
      msg: '添加使用记录失败',
      data: null
    });
  }
}

module.exports = {
    find,
    findAll,
    add,
    update,
    remove,
    getOverdueDevices,
    returnDevice,
    cancelBooking,
    getUsageRecords,
    addUsageRecord
};



